package com.woniuxy.food.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.food.infra.mapper.*;
import com.woniuxy.food.infra.model.*;
import com.woniuxy.food.service.FoodSpuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.food.service.servicedto.FoodPropServiceDto;
import com.woniuxy.food.service.servicedto.FoodPropValueServiceDto;
import com.woniuxy.food.service.servicedto.FoodSpuServiceDto;
import com.woniuxy.food.service.serviceparam.*;
import common.WoniuPage;
import exception.MallException;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import result.CommonResultCodeEnum;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 菜品spu表 服务实现类
 * </p>
 *
 * @author 刘德华
 * @since 2023-07-19
 */
@Service
public class FoodSpuServiceImpl extends ServiceImpl<FoodSpuMapper, FoodSpu> implements FoodSpuService {

    @Autowired
    private FoodSpuMapper foodSpuMapper;
    @Autowired
    private FoodSkuMapper foodSkuMapper;
    @Autowired
    private FoodTypeSpuMapper foodTypeSpuMapper;
    @Autowired
    private FoodTypeMapper foodTypeMapper;
    @Autowired
    private FoodPropMapper foodPropMapper;
    @Autowired
    private FoodPropValueMapper foodPropValueMapper;
    @Autowired
    private FoodPicMapper foodPicMapper;
    @Override
    @GlobalTransactional
    public void insertFoodSpu(InsertFoodSpuServiceParam param) {
        QueryWrapper<FoodType> foodTypeQueryWrapper = new QueryWrapper<>();
        foodTypeQueryWrapper.eq("food_type_id",param.getFoodTypeId()).eq("store_id",param.getStoreId());
        FoodType foodType = foodTypeMapper.selectOne(foodTypeQueryWrapper);
        if (foodType==null) {
            throw new MallException("当前菜品类型不存在",CommonResultCodeEnum.INVALID_PARAM);
        }
        QueryWrapper<FoodSpu> foodSpuQueryWrapper = new QueryWrapper<>();
        foodSpuQueryWrapper.eq("store_id",param.getStoreId()).eq("spu_name",param.getSpuName());
        FoodSpu foodSpu = foodSpuMapper.selectOne(foodSpuQueryWrapper);
        if (foodSpu!=null) {
            throw new MallException("菜品spu名称不可以重复",CommonResultCodeEnum.INVALID_PARAM);
        }
        QueryWrapper<FoodPic> foodPicQueryWrapper = new QueryWrapper<>();
        foodPicQueryWrapper.eq("store_id",param.getStoreId()).eq("food_pic_id",param.getFoodPicId());
        FoodPic foodPic = foodPicMapper.selectOne(foodPicQueryWrapper);
        if (foodPic==null) {
            throw new MallException("当前图片不存在",CommonResultCodeEnum.INVALID_PARAM);
        }
        FoodSpu foodSpuNew = BeanUtil.toBean(param, FoodSpu.class);
        foodSpuNew.setMainPic(foodPic.getPicPath());
        foodSpuNew.setCreatTime(new Date());
        foodSpuNew.setSalesCount(0L);
        foodSpuNew.setSpuState("FORBID");
        save(foodSpuNew);
        FoodTypeSpu foodTypeSpu = BeanUtil.toBean(param, FoodTypeSpu.class);
        foodTypeSpu.setSpuId(foodSpuNew.getSpuId());
        foodTypeSpuMapper.insert(foodTypeSpu);
    }

    @Override
    @GlobalTransactional
    public void updateFoodSpuStateByIds(UpdateFoodSpuStateServiceParam param) {
        List<Integer> ids = Arrays.asList(param.getIds());
        List<FoodSpu> foodSpus = new ArrayList<>();
        for (Integer id : ids) {
            FoodSpu foodSpu = selectFoodSpuByIdAndStoreId(id, param.getStoreId());
            foodSpus.add(foodSpu);
        }
        for (FoodSpu foodSpu : foodSpus) {
            if (foodSpu.getSpuState().equals(param.getSpuState())) {
                throw new MallException("有菜品spu已为该状态",CommonResultCodeEnum.INVALID_PARAM);
            }
            if ("FORBID".equals(param.getSpuState())) {
                QueryWrapper<FoodSku> foodSkuQueryWrapper = new QueryWrapper<>();
                foodSkuQueryWrapper.eq("spu_id",foodSpu.getSpuId());
                List<FoodSku> foodSkus = foodSkuMapper.selectList(foodSkuQueryWrapper);
                for (FoodSku skus : foodSkus) {
                    if (skus.getSkuState().equals("NORMAL")) {
                        throw new MallException("有菜品sku为下架状态",CommonResultCodeEnum.INVALID_PARAM);
                    }
                }
            }
        }
        for (FoodSpu foodSpu : foodSpus) {
            foodSpu.setSpuState(param.getSpuState());
            foodSpuMapper.updateById(foodSpu);
        }
    }

    @Override
    @GlobalTransactional
    public void updateFoodSpuById(UpdateFoodSpuServiceParam param) {
        QueryWrapper<FoodPic> foodPicQueryWrapper = new QueryWrapper<>();
        foodPicQueryWrapper.eq("store_id",param.getStoreId()).eq("food_pic_id",param.getFoodPicId());
        FoodPic foodPic = foodPicMapper.selectOne(foodPicQueryWrapper);
        if (foodPic==null) {
            throw new MallException("当前图片不存在",CommonResultCodeEnum.INVALID_PARAM);
        }
        FoodSpu foodSpu = selectFoodSpuByIdAndStoreId(param.getSpuId(), param.getStoreId());
        foodSpu.setSpuName(param.getSpuName());
        foodSpu.setDescription(param.getDescription());
        foodSpu.setMainPic(foodPic.getPicPath());
        foodSpuMapper.updateById(foodSpu);
    }

    @Override
    @GlobalTransactional
    public void updateFoodSpuSalesCountById(UpdateFoodSpuSalesCountServiceParam param) {
        FoodSpu foodSpu = selectFoodSpuByIdAndStoreId(param.getSpuId(), param.getStoreId());
        foodSpu.setSalesCount(foodSpu.getSalesCount()+param.getSalesCount());
        foodSpuMapper.updateById(foodSpu);
    }

    @Override
    @GlobalTransactional
    public void deleteFoodSpuByIds(Integer storeId, Integer[] ids) {
        List<Integer> idList = Arrays.asList(ids);
        List<FoodSpu> foodSpus = new ArrayList<>();
        for (Integer id : idList) {
            FoodSpu foodSpu = selectFoodSpuByIdAndStoreId(id,storeId);
            QueryWrapper<FoodSku> foodSkuQueryWrapper = new QueryWrapper<>();
            foodSkuQueryWrapper.eq("spu_id",id);
            List<FoodSku> foodSkus = foodSkuMapper.selectList(foodSkuQueryWrapper);
            if (foodSkus.size()!=0) {
                throw new MallException("菜品spu下还存在菜品sku", CommonResultCodeEnum.INVALID_PARAM);
            }
            QueryWrapper<FoodProp> foodPropQueryWrapper = new QueryWrapper<>();
            foodPropQueryWrapper.eq("spu_id",id);
            List<FoodProp> foodProps = foodPropMapper.selectList(foodPropQueryWrapper);
            if (foodProps.size()!=0) {
                throw new MallException("菜品spu下还存在菜品属性", CommonResultCodeEnum.INVALID_PARAM);
            }
            foodSpus.add(foodSpu);
        }
        for (FoodSpu foodSpu : foodSpus) {
            foodSpuMapper.deleteById(foodSpu);
        }
    }

    @Override
    public WoniuPage<FoodSpuServiceDto> searchFoodSpuByCondition(SearchFoodSpuByConditionServiceParam param) {
        Integer pageNum=param.getPageIndex();
        Integer pageSize=param.getPageSize();
        if (pageNum==null) {
            pageNum=1;
        }
        if (pageSize==null) {
            pageSize=5;
        }
        Page<FoodSpu> page = new Page<>(pageNum,pageSize);

        if (param.getFoodTypeId()!=null) {
            if (param.getOrderType()!=null&&!"".equals(param.getOrderType())) {
                if (param.getOrderType().equals("升序")) {
                    getBaseMapper().searchFoodSpuByConditionAsc(page, param.getStoreId(), param.getFoodTypeId(), param.getKeyword(), param.getSpuState());
                }
                if (param.getOrderType().equals("降序")) {
                    getBaseMapper().searchFoodSpuByConditionDesc(page,param.getStoreId(),param.getFoodTypeId(),param.getKeyword(),param.getSpuState());
                }
            }
            getBaseMapper().searchFoodSpuByConditionDesc(page,param.getStoreId(),param.getFoodTypeId(),param.getKeyword(),param.getSpuState());
        }else {
            if (param.getOrderType()!=null&&!"".equals(param.getOrderType())) {
                if (param.getOrderType().equals("升序")) {
                    getBaseMapper().searchFoodSpuByConditionAscNoTypeId(page,param.getStoreId(),param.getKeyword(),param.getSpuState());
                }
                if (param.getOrderType().equals("降序")) {
                    getBaseMapper().searchFoodSpuByConditionDescNoTypeId(page,param.getStoreId(),param.getKeyword(),param.getSpuState());
                }
            }
            getBaseMapper().searchFoodSpuByConditionDescNoTypeId(page,param.getStoreId(),param.getKeyword(),param.getSpuState());
        }

        WoniuPage<FoodSpuServiceDto> woniuPage = new WoniuPage<>();
        woniuPage.setTotal(page.getTotal());
        woniuPage.setPages(page.getPages());
        woniuPage.setPageIndex(page.getCurrent());
        woniuPage.setPageSize(page.getSize());
        List<FoodSpuServiceDto> foodSpuServiceDtos = new ArrayList<>();
        for (FoodSpu foodSpu : page.getRecords()) {
            FoodSpuServiceDto foodSpuServiceDto = BeanUtil.toBean(foodSpu, FoodSpuServiceDto.class);

            List<FoodProp> props = foodPropMapper.selectList(new QueryWrapper<FoodProp>().eq("spu_id", foodSpu.getSpuId()));
            List<FoodPropServiceDto> foodPropServiceDtos = BeanUtil.copyToList(props, FoodPropServiceDto.class);

            for (FoodPropServiceDto foodPropServiceDto : foodPropServiceDtos) {
                QueryWrapper<FoodPropValue> foodPropValueQueryWrapper = new QueryWrapper<>();
                foodPropValueQueryWrapper.eq("prop_id",foodPropServiceDto.getPropId());
                List<FoodPropValue> foodPropValues = foodPropValueMapper.selectList(foodPropValueQueryWrapper);
                List<FoodPropValueServiceDto> foodPropValueServiceDtos = BeanUtil.copyToList(foodPropValues, FoodPropValueServiceDto.class);
                foodPropServiceDto.setFoodPropValueServiceDtos(foodPropValueServiceDtos);
            }
            foodSpuServiceDto.setFoodPropServiceDtos(foodPropServiceDtos);
            foodSpuServiceDtos.add(foodSpuServiceDto);
        }
        woniuPage.setList(foodSpuServiceDtos);
        return woniuPage;
    }

    @Override
    public FoodSpuServiceDto searchFoodSpuBySkuId(Integer skuId) {
        FoodSku foodSku = foodSkuMapper.selectById(skuId);
        if (foodSku==null) {
            throw new MallException("菜品sku不存在", CommonResultCodeEnum.INVALID_PARAM);
        }
        FoodSpu foodSpu = foodSpuMapper.selectById(foodSku.getSpuId());
        FoodSpuServiceDto foodSpuServiceDto = BeanUtil.toBean(foodSpu, FoodSpuServiceDto.class);
        return foodSpuServiceDto;
    }

    @Override
    public List<FoodSpuServiceDto> getSpuByStoreId(Integer storeId) {
        QueryWrapper<FoodSpu> foodSpuQueryWrapper = new QueryWrapper<>();
        foodSpuQueryWrapper.eq("store_id",storeId);
        List<FoodSpu> foodSpus = foodSpuMapper.selectList(foodSpuQueryWrapper);
        List<FoodSpuServiceDto> foodSpuServiceDtos = new ArrayList<>();
        for (FoodSpu foodSpu : foodSpus) {
            FoodSpuServiceDto foodSpuServiceDto = BeanUtil.toBean(foodSpu, FoodSpuServiceDto.class);

            List<FoodProp> props = foodPropMapper.selectList(new QueryWrapper<FoodProp>().eq("spu_id", foodSpu.getSpuId()));
            List<FoodPropServiceDto> foodPropServiceDtos = BeanUtil.copyToList(props, FoodPropServiceDto.class);

            for (FoodPropServiceDto foodPropServiceDto : foodPropServiceDtos) {
                QueryWrapper<FoodPropValue> foodPropValueQueryWrapper = new QueryWrapper<>();
                foodPropValueQueryWrapper.eq("prop_id",foodPropServiceDto.getPropId());
                List<FoodPropValue> foodPropValues = foodPropValueMapper.selectList(foodPropValueQueryWrapper);
                List<FoodPropValueServiceDto> foodPropValueServiceDtos = BeanUtil.copyToList(foodPropValues, FoodPropValueServiceDto.class);
                foodPropServiceDto.setFoodPropValueServiceDtos(foodPropValueServiceDtos);
            }
            foodSpuServiceDto.setFoodPropServiceDtos(foodPropServiceDtos);
            foodSpuServiceDtos.add(foodSpuServiceDto);
        }
        return foodSpuServiceDtos;
    }

    private FoodSpu selectFoodSpuByIdAndStoreId(Integer spuId,Integer storeId){
        QueryWrapper<FoodSpu> foodSpuQueryWrapper = new QueryWrapper<>();
        foodSpuQueryWrapper.eq("store_id",storeId).eq("spu_id",spuId);
        FoodSpu foodSpu = foodSpuMapper.selectOne(foodSpuQueryWrapper);
        if (foodSpu==null) {
            throw new MallException("菜品spu不存在", CommonResultCodeEnum.INVALID_PARAM);
        }
        return foodSpu;
    }
}
